package sample.components
{
	import asf.interfaces.IComboBox;
	import asf.utils.FX;
	
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.utils.Dictionary;

	public class Dropdown extends Sprite implements IComboBox
	{
		private var masterItem:DropdownItem;
		private var container:Sprite;
		private var itemsOutside:Sprite;
		private var items:Array;
		private var data:Array;
		private var dict:Dictionary;
		private var selectedIndex:int = -1;
		
		public function Dropdown( )
		{
			super( );
			
			masterItem = new DropdownItem( "", null );
			container = new Sprite( );
			itemsOutside = new Sprite( );
			
			items = new Array( );
			data = new Array( );
			dict = new Dictionary( true );
			
			itemsOutside.y = masterItem.height + 3;
			itemsOutside.visible = false;
			itemsOutside.alpha = 0;
			
			masterItem.addEventListener( MouseEvent.CLICK, masterClick );
			masterItem.buttonMode = true;
			
			addChild( masterItem );
			addChild( itemsOutside );
			itemsOutside.addChild( container );
		}
		
		public function dispose( ):void
		{
			var item:DropdownItem;
			
			for each( item in items )
			{
				container.removeChild( item );
				item.removeEventListener( MouseEvent.CLICK, itemClick );
				item = null;
			}
			
			masterItem.removeEventListener( MouseEvent.CLICK, masterClick );
			
			itemsOutside.removeChild( container );
			removeChild( itemsOutside );
			removeChild( masterItem );
			
			masterItem = null;
			container = null;
			itemsOutside = null;
			
			items = null;
			data = null;
		}
		
		public function setMaxVisible(value:uint):void
		{
		}
		
		public function addItem( label:String, value:* ):void
		{
			var item:DropdownItem = new DropdownItem( label, value );
			
			item.y = items.length * ( item.height + 2 );
			item.addEventListener( MouseEvent.CLICK, itemClick );
			
			container.addChild( item );
			
			dict[ item ] = items.length;
			
			items.push( item );
			data.push( value );
		}
		
		private function masterClick( evt:MouseEvent ):void
		{
			open( );
		}
		
		private function itemClick( evt:MouseEvent ):void
		{
			var item:DropdownItem = evt.currentTarget as DropdownItem;
			setSelectedIndex( dict[ item ] );
			
			close( );
		}
		
		public function getValue( ):*
		{
			return masterItem.getValue( );
		}
		
		public function open( ):void
		{
			FX.fadeIn( itemsOutside );
			
			if( parent )
			{
				parent.swapChildren( this, parent.getChildAt( parent.numChildren - 1 ) );
			}
		}
		
		public function close( ):void
		{
			FX.fadeOut( itemsOutside );
		}
		
		public function setValue( value:* ):void
		{
			var item:DropdownItem;
			var n:uint = 0;
			
			for each( item in items )
			{
				if( item.getValue( ) == value )
				{
					setSelectedIndex( n );
					return;
				}
				
				n++;
			}
			
			setSelectedIndex( - 1 );
		}
		
		public function getMaxVisible( ):uint
		{
			return 0;
		}
		
		public function clearValue( ):void
		{
			clear( );
		}
		
		public function clear( ):void
		{
			masterItem.setLabel( "" );
			masterItem.setValue( null );
		}
		
		public function focus( ):void
		{
		}
		
		public function isSelected( ):Boolean
		{
			return selectedIndex >= 0;
		}
		
		public function blur( ):void
		{
		}
		
		public function setSelectedIndex(index:int):void
		{
			var item:DropdownItem;
			
			selectedIndex = index;
			
			if( index < 0 || index >= items.length )
			{
				if( index >= items.length ) setSelectedIndex( -1 );
				return;
			}
			
			item = items[ index ];
			
			masterItem.setLabel( item.getLabel( ) );
			masterItem.setValue( item.getValue( ) );
		}
		
		public function setWidth(value:Number):void
		{
		}
		
		public function setHeight(value:Number):void
		{
		}
		
		public function getWidth():Number
		{
			return 0;
		}
		
		public function getHeight():Number
		{
			return 0;
		}
		
		public function setTabIndex(value:int):void
		{
		}
		
		public function getTabIndex():int
		{
			return 0;
		}
		
		public function enable():void
		{
			alpha = 1;
			mouseEnabled = false;
			mouseChildren = false;
		}
		
		public function disable():void
		{
			alpha = 0.5;
			mouseEnabled = true;
			mouseChildren = true;
		}
		
		public function isValid():Boolean
		{
			return true;
		}
		
		public function isEmpty():Boolean
		{
			return selectedIndex < 0;
		}
		
		public function markError(message:String):void
		{
			
		}
		
		public function clearError():void
		{
		}
		
	}
}